package com.feiwo.nonego.rpc.proxy.javassist;

import com.feiwo.nonego.rpc.proxy.api.BaseProxyFactory;
import com.feiwo.nonego.rpc.proxy.api.ProxyFactory;
import com.feiwo.nonego.rpc.spi.annotation.SPIClass;
import javassist.util.proxy.ProxyObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;

/**
 *
 *
 * @author feiwo 2025-08-14
 */
@SPIClass
public class JavassistProxyFactory<T> extends BaseProxyFactory<T> implements ProxyFactory {

    private static final Logger logger = LoggerFactory.getLogger(JavassistProxyFactory.class);
    private final javassist.util.proxy.ProxyFactory proxyFactory = new javassist.util.proxy.ProxyFactory();

    @SuppressWarnings("unchecked")
    @Override
    public <T> T getProxy(Class<T> clazz) {
        proxyFactory.setInterfaces(new Class[]{clazz});
        var proxyClass = proxyFactory.createClass();
        try {
            var proxy = proxyClass.getDeclaredConstructor().newInstance();
            if (proxy instanceof ProxyObject) {
                ((ProxyObject) proxy).setHandler((self, thisMethod, proceed, args) -> objectProxy.invoke(self, thisMethod, args));
            }
            return (T) proxy;
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            logger.error("javassist create proxy throws ex ---> ", e);
        }
        return null;
    }
}
